package cn.stu.framework.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.stu.common.utils.ApiData;
import cn.stu.framework.dto.MenuDto;
import cn.stu.framework.entity.Menu;
import cn.stu.framework.mapper.MenuMapper;
import cn.stu.framework.service.MenuService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;


/**
 * 菜单服务实施
 *
 * @author 郑志豪
 * @date 2023/09/11
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {

    /**
     * 马普
     */
    @Autowired
    private MenuMapper mapper;

    /**
     * 菜单列表
     *
     * @param dto DTO
     * @return {@link ApiData}
     */
    @Override
    @Cacheable(value = "MenuList", sync = true)
    public ApiData menuList(MenuDto dto) {
        QueryWrapper<Menu> wr = new QueryWrapper<>();
        wr.like(StrUtil.isNotBlank(dto.getTitle()), "title", dto.getTitle());
        wr.eq(dto.getPid() != null, "pid", dto.getPid()).or().eq(dto.getPid() != null, "menu_id", dto.getPid());
        if ((dto.getPage() == null && dto.getLimit() == null)) {
            List<Menu> menus = mapper.selectList(wr);
            return ApiData.getTrue("获取成功", menus);
        }
        Page<Menu> page = new Page<>(dto.getPage(), dto.getLimit());
        List<Menu> list = mapper.selectPage(page, wr).getRecords();
        if (list == null) {
            return ApiData.getFalse("获取失败");
        }
        return ApiData.getPageTrue("获取成功", page.getTotal(), list);
    }

    /**
     * 菜单添加
     *
     * @param add 添加
     * @return {@link ApiData}
     */
    @Override
    @Caching(evict = {
            @CacheEvict(value = "MenuList", allEntries = true, beforeInvocation = true),
            @CacheEvict(value = "routes", allEntries = true, beforeInvocation = true)
    })
    public ApiData menuAdd(Menu add) {
        if (StrUtil.isBlank(add.getTitle())) {
            return ApiData.getFalse("菜单名为空！");
        }
        if (StrUtil.isBlank(add.getPath())) {
            return ApiData.getFalse("路由地址为空！");
        }
        if (StrUtil.isBlank(add.getComponent())) {
            return ApiData.getFalse("组件路径为空！");
        }
        if (add.getPid() != 0) {
            boolean exists = mapper.exists(lambdaQuery().eq(Menu::getMenuId, add.getPid()).getWrapper());
            if (!exists) {
                return ApiData.getFalse("父菜单不存在！");
            }
        }
        if (StrUtil.isBlank(add.getPath())) {
            return ApiData.getFalse("菜单地址不存在!");
        }
        mapper.insert(add);
        return ApiData.getTrue("添加成功！");
    }

    /**
     * 菜单更新
     *
     * @param update 更新
     * @return {@link ApiData}
     */
    @Override
    @Caching(evict = {
            @CacheEvict(value = "MenuList", allEntries = true, beforeInvocation = true),
            @CacheEvict(value = "routes", allEntries = true, beforeInvocation = true)
    })
    public ApiData menuUpdate(Menu update) {
        if (update.getMenuId() == null) {
            return ApiData.getFalse("菜单id不能为空！");
        }
        if (Objects.equals(update.getMenuId(), update.getPid())) {
            return ApiData.getFalse("不能成为自己的子菜单！");
        }
        if (StrUtil.isBlank(update.getPath())) {
            return ApiData.getFalse("路由地址为空！");
        }
        if (StrUtil.isBlank(update.getComponent())) {
            return ApiData.getFalse("组件路径为空！");
        }
        if (StrUtil.isBlank(update.getTitle())) {
            return ApiData.getFalse("菜单名为空！");
        }
        if (update.getPid() != 0) {
            boolean exists = mapper.exists(lambdaQuery().eq(Menu::getMenuId, update.getPid()).getWrapper());
            if (!exists) {
                return ApiData.getFalse("父菜单不存在！");
            }
        }
        if (update.getPid() != 1) {
            if (StrUtil.isBlank(update.getPath())) {
                return ApiData.getFalse("菜单地址不存在!");
            }
        }
        mapper.updateById(update);
        return ApiData.getFalse("修改失败！");
    }

    /**
     * 删除菜单
     *
     * @param menuId 菜单ID
     * @return {@link ApiData}
     */
    @Override
    @Caching(evict = {
            @CacheEvict(value = "MenuList", allEntries = true, beforeInvocation = true),
            @CacheEvict(value = "routes", allEntries = true, beforeInvocation = true)
    })
    public ApiData menuDel(Long menuId) {
        boolean exists = mapper.exists(lambdaQuery().eq(Menu::getMenuId, menuId).getWrapper());
        if (!exists) {
            return ApiData.getFalse("参数错误！");
        }
        removeById(menuId);
        return ApiData.getFalse("删除失败！");
    }

    /**
     * 菜单信息
     *
     * @param menuId 菜单ID
     * @return {@link ApiData}
     */
    @Override
    public ApiData menuInfo(Long menuId) {
        if (menuId == null) {
            return ApiData.getTrue("获取成功", list());
        }
        Menu m = mapper.selectById(menuId);
        if (m == null) {
            return ApiData.getFalse("id不存在！");
        }
        return ApiData.getTrue("获取成功", m);
    }
}
